﻿/*  ----------------------------------------------------------------------------
 *  SysServer
 *  ----------------------------------------------------------------------------
 *  File:       TStack`1.cs
 *  Creater:     SEEN\MistSeen
 *  ----------------------------------------------------------------------------
 *  $Date: 2010-09-06 10:36:01 +0000 (Mon, 06 Sep 2010) $
 *  $Rev: 15 $
 *  $Author: ScorDeity $
 *  $URL: http://sysserver.googlecode.com/svn/trunk/src/SysServer/Collections/Generic/TStack%601.cs $
 *  $Id: TStack`1.cs 15 2010-09-06 10:36:01Z ScorDeity $
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace SysServer.Collections.Generic
{
    public class TStackItem<T> : TEntity
    {
        public T Data;
        public TStackItem<T> Next;

        public TStackItem()
        {

        }
        public TStackItem(T value)
        {
            this.Init(value);
        }
        public override void Initialize()
        {
            this.Init(default(T));
        }
        private void Init(T data)
        {
            this.Data = data;
            this.Next = null;
        }
    }

    public class TStack<T>
    {
        private TStackItem<T> _Head;

        public TStack()
        {
            this._Head = new TStackItem<T>();
        }
        public void Push(T data)
        {
            TStackItem<T> newItem = new TStackItem<T>();
            newItem.Data = data;

            do
            {
                newItem.Next = this._Head.Next;
            } while (Interlocked.CompareExchange<TStackItem<T>>(ref this._Head.Next, newItem, newItem.Next) != newItem.Next);
        }

        public bool Pop(out T data)
        {
            TStackItem<T> tempNode;
            do
            {
                tempNode = this._Head.Next;
                if (tempNode == null)
                {
                    data = default(T);
                    return false;
                }
            } while (Interlocked.CompareExchange<TStackItem<T>>(ref this._Head.Next,tempNode.Next,tempNode)!= tempNode );

            data = tempNode.Data;
            return true;
        }
        public T Pop()
        {
            T result;
            Pop(out result);
            return result;
        }
    }
}